Factory Pattern

Factory Pattern က Creational Pattern တစ်ခု ဖြစ်ပါတယ်။ Factory ဆိုသည့် အတိုင်း စက်ရုံကနေ ပစ္စည်း ထုတ် သလို object တွေကို ဖန်တီးပေးသည့် pattern တစ်ခုပါ။

Factory pattern မသုံးခင်မှာ Object တွေကို လက်ရှိ code တွေထဲကနေ ရောရေးပြီး ဖန်တီးပါတယ်။ Factory pattern က single responsibility ဖြစ်ပြီး separation of concern အရ object ဖန်တီး မှု ကို ခွဲထုတ်ရေးသားလိုက်ခြင်း မျိုးပါပဲ။

ဥပမာ CreditCardFactory ကနေ CreditCard ကို generate လုပ်ပေးထားပါတယ်။

public class CreditCardFactory {
 static CreditCard getCreditCardInstance(String type, String number, double limit,double annualCharge) { 
  return new CreditCard(type, number, limit, annualCharge);
 }
}
public class Application {
  public static void main(String[] args) {
    CreditCard creditCard2 = CreditCardFactory.getCreditCardInstance("visa","4111111111111111", 2500.0, 10) 
  }
}

တိုက်ရိုက်ခေါ်မသုံးပဲ Factory pattern ကနေ generate လုပ်သုံးသင့်လဲ ဆိုတာကတော့ လိုအပ်သည့် data တွေကို encapsulation လုပ်လို့ရအောင်ပါ။ ဥပမာ credit card ကို မပို့ခင်မှာ အခြား validation တွေ စစ်ဆေးတာမျိုးတွေ ထည့်သွင်းလို့ရပါတယ်။

ထပ်ပြီး ဥပမာ ကြည့်ရအောင်။ Factory Pattern မသုံးခင် java code ကို ကြည့်ရအောင်။

public class Shape {
  public void draw() {
    System.out.println("Drawing a shape");
  }
}

public class Circle extends Shape {
  @Override
  public void draw() {
    System.out.println("Drawing a circle");
  }
}

public class Rectangle extends Shape {
  @Override
  public void draw() {
    System.out.println("Drawing a rectangle");
  }
}

public class Client {
  public static void main(String[] args) {
    Shape circle = new Circle();
    circle.draw();

    Shape rectangle = new Rectangle();
    rectangle.draw();
  }
}

Client class က Circle နဲ့ Rectangle ကို main class ထဲမှာ ထည့်ရေးထားပါတယ်။

Factory pattern ပြောင်းပြီး ရေးမယ် ဆိုရင်

// Shape interface
public interface Shape {
  void draw();
}

// Concrete Shape classes
public class Circle implements Shape {
  @Override
  public void draw() {
    System.out.println("Drawing a circle");
  }
}

public class Rectangle implements Shape {
  @Override
  public void draw() {
    System.out.println("Drawing a rectangle");
  }
}

// Factory class
public class ShapeFactory {
  public static Shape getShape(String shapeType) {
    if (shapeType.equals("circle")) {
      return new Circle();
    } else if (shapeType.equals("rectangle")) {
      return new Rectangle();
    } else {
      throw new IllegalArgumentException("Invalid shape type");
    }
  }
}

// Client code
public class Client {
  public static void main(String[] args) {
    Shape circle = ShapeFactory.getShape("circle");
    circle.draw();

    Shape rectangle = ShapeFactory.getShape("rectangle");
    rectangle.draw();
  }
}

Factory Pattern ဟာ proxy pattern နဲ့ တွဲပြီး အသုံးပြုနိုင်ပါတယ်။ Proxy Pattern မှာ class တစ်ခုကနေ နောက်တစ်ခု ကို ဆင့်ကာဆင့်ကာ  ခေါ်သွားသည့် အခါမှာ proxy တွေ ကို တစ်ခု ခြင်းဆီ create လုပ်နေရပါတယ်။ အဲဒီ အစား Factory Pattern ကနေ generate လုပ်ပေးနိုင်ပါတယ်။

Factory Pattern မှာ နောက်ထပ်ရှိသည့် တစ်မျိုးကတော့ Factory က Factory ကို interface လုပ်ပြီး သက်ဆိုင်ရာ class ပြန်ထုတ် ပေးတာမျိုးပါ။​ ဥပမာ PhoneFactory လိုမျိုးပေါ့။

Factory pattern ကို Unit Testing တွေမှာလည်း အသုံးပြုပါတယ်။ Unit Testing အတွက်ဆိုရင် Mock ကို generate လုပ်ပြီး code run သည့် အခါမှာတော့ သက်ဆိုင်ရာ code ကို ထုတ်ပေးသည့် သဘောမျိုးပေါ့။

Pros and Cons

Tight coupling မဖြစ်အောင် ရှောင်ရှားနိုင်ပါတယ်။

Single Responsibility နဲ့ Open/Closed Principle ကို လိုက်နာ ထားပါတယ်။

မကောင်းတာကတော့ code တွေ complicated ဖြစ်နိုင်ပါတယ်။ မလိုအပ်ပဲ subclass တွေ များလာနိုင်ပါတယ်။